#pragma once

#include <string>
#include <unordered_map>

#include "util.h"
#include "mutex_guard.h"
// #include "timer_manager.h"
#include "event_loop.h"
#include "channel.h"


const int STATE_PARSE_URI = 1;
const int STATE_PARSE_HEADERS = 2;
const int STATE_RECV_BODY = 3;
const int STATE_ANALYSIS = 4;
const int STATE_FINISH = 5;



const int AGAIN_MAX_TIMES = 200;

const int PARSE_URI_AGAIN = -1;
const int PARSE_URI_ERROR = -2;
const int PARSE_URI_SUCCESS = 0;

const int PARSE_HEADER_AGAIN = -1;
const int PARSE_HEADER_ERROR = -2;
const int PARSE_HEADER_SUCCESS = 0;

const int ANALYSIS_ERROR = -2;
const int ANALYSIS_SUCCESS = 0;

const int METHOD_POST = 1;
const int METHOD_GET = 2;
const int METHOD_INVALID = 2;

const int HTTP_10 = 1;
const int HTTP_11 = 2;
const int EPOLL_WAIT_TIME = 500;

const int TIME_OUT = 1000;

class MimeType { //  描述消息内容
private:
    static pthread_mutex_t lock; //对于MimeType的互斥保护
    static std::unordered_map <std::string, std::string> mime;
    MimeType();
    MimeType(const MimeType &m);
public:
    static std::string getMime(const std::string &suffix);
};

enum HeadersState {
    H_START = 0,
    H_KEY,
    H_COLON,
    H_SPACES_AFTER_COLON,
    H_VALUE,
    H_CR,
    H_LF,
    H_END_CR,
    H_END_LF
};

// 循环依赖需要使用前向声明
class MyTimer;

class RequestData : public std::enable_shared_from_this<RequestData>{
public:
    RequestData(EventLoop* loop, int fd);
    ~RequestData();

    void ConnectionEstablished();

    int GetFd(){
        return fd_;
    }
    void SetFd(int fd){
        fd_ = fd;
    }

    void SeperateTimer();
    void SetTimer(std::shared_ptr<MyTimer>);

    void Reset();

    void HandleRead();
    void HandleWrite();
    void HandleError(int fd, int err_num, std::string short_msg);
    void HandleConn();
    void HandleClose();


    void AddTimer();

private:
    int ParseURI();
    int ParseHeaders();
    int AnalysisRequest(); //响应请求

private:
    int fd_;
    ChannelPtr channel_;
    EventLoop* loop_;

    // std::weak_ptr<MyTimer> timer_;

    std::string content_;
    int againTimes_;

    int method_;
    int HTTPversion_;
    std::string fileName_; //请求的文件名
    std::string inBuffer_;
    std::string outBuffer_;

    int state_; // 整体状态
    int hState_; // header状态
    int nowReadPos_;

    bool isFinish_;
    bool keepAlive_; //是否是长连接
    std::unordered_map <std::string, std::string> headers_;  //存储请求头键值对

    bool interError_;
    bool error_;
};

using RequestDataPtr = std::shared_ptr<RequestData>;
